import 'package:flutter/material.dart';

// 开口方向枚举
enum GapDirection {
  top, // 顶部开口
  right, // 右侧开口
  bottom, // 底部开口
  left, // 左侧开口
}

class ProgressRing extends StatefulWidget {
  final double progress; // 进度值 0.0 - 1.0
  final double size; // 组件大小
  final double strokeWidth; // 圆环宽度
  final Duration animationDuration; // 动画持续时间
  final List<Color> gradientColors; // 渐变色彩
  final Color backgroundColor; // 背景色
  final TextStyle? textStyle; // 文字样式
  final bool showPercentage; // 是否显示百分比
  final double gapAngle; // 圆弧开口角度（弧度），0表示完整圆环
  final GapDirection gapDirection; // 开口方向
  final bool showShadow;

  const ProgressRing({
    super.key,
    required this.progress,
    this.size = 200.0,
    this.strokeWidth = 8.0,
    this.animationDuration = const Duration(milliseconds: 1000),
    this.showShadow = true,
    this.gradientColors = const [
      Color(0xFF6B73FF),
      Color(0xFF9B59B6),
      Color(0xFFE91E63),
    ],
    this.backgroundColor = const Color(0xFFE8E8E8),
    this.textStyle,
    this.showPercentage = true,
    this.gapAngle = 0.5, // 默认有小开口
    this.gapDirection = GapDirection.bottom, // 默认底部开口
  });

  @override
  State<ProgressRing> createState() => _ProgressRingState();
}

class _ProgressRingState extends State<ProgressRing> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _animation;
  double _currentProgress = 0.0;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: widget.animationDuration,
      vsync: this,
    );

    _animation = Tween<double>(
      begin: 0.0,
      end: widget.progress,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));

    _animation.addListener(() {
      setState(() {
        _currentProgress = _animation.value;
      });
    });

    // 启动动画
    _animationController.forward();
  }

  @override
  void didUpdateWidget(ProgressRing oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.progress != widget.progress) {
      _updateProgress();
    }
  }

  void _updateProgress() {
    _animation = Tween<double>(
      begin: _currentProgress,
      end: widget.progress,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));

    _animationController.reset();
    _animationController.forward();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.size,
      height: widget.size,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(widget.size / 2),
        boxShadow: widget.showShadow
            ? [
                BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 10,
                  offset: const Offset(0, 5),
                ),
              ]
            : null,
      ),
      child: Stack(
        alignment: Alignment.center,
        children: [
          // 进度圆环
          CustomPaint(
            size: Size(widget.size, widget.size),
            painter: ProgressRingPainter(
              progress: _currentProgress,
              strokeWidth: widget.strokeWidth,
              gradientColors: widget.gradientColors,
              backgroundColor: widget.backgroundColor,
              gapAngle: widget.gapAngle,
              gapDirection: widget.gapDirection,
            ),
          ),
          Container(
              width: widget.size / 2,
              height: widget.size / 2,
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      Colors.white.withOpacity(0.8), // 80% 透明度
                      Colors.white.withOpacity(0), // 20% 透明度
                    ],
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                  ),
                  borderRadius: BorderRadius.circular(widget.size / 2))),
          // 百分比文字
          if (widget.showPercentage)
            Text(
              '${(_currentProgress * 100).round()}%',
              style: widget.textStyle ??
                  TextStyle(
                    fontSize: widget.size * 0.13,
                    fontWeight: FontWeight.bold,
                    color: const Color(0xFF2D3748),
                  ),
            ),
        ],
      ),
    );
  }
}

class ProgressRingPainter extends CustomPainter {
  final double progress;
  final double strokeWidth;
  final List<Color> gradientColors;
  final Color backgroundColor;
  final double gapAngle;
  final GapDirection gapDirection;

  ProgressRingPainter({
    required this.progress,
    required this.strokeWidth,
    required this.gradientColors,
    required this.backgroundColor,
    required this.gapAngle,
    required this.gapDirection,
  });

  // 根据开口方向计算起始角度
  double get _startAngle {
    switch (gapDirection) {
      case GapDirection.top:
        return -1.5708 + gapAngle / 2; // 顶部开口，从右上开始
      case GapDirection.right:
        return gapAngle / 2; // 右侧开口，从右下开始
      case GapDirection.bottom:
        return 1.5708 + gapAngle / 2; // 底部开口，从左下开始
      case GapDirection.left:
        return 3.14159 + gapAngle / 2; // 左侧开口，从左上开始
    }
  }

  // 创建平滑的渐变色彩数组
  List<Color> _createSmoothGradient(List<Color> colors, int segments) {
    if (colors.length < 2) return colors;

    List<Color> smoothColors = [];

    for (int i = 0; i < colors.length - 1; i++) {
      Color startColor = colors[i];
      Color endColor = colors[i + 1];

      // 在每两个颜色之间插入过渡色
      for (int j = 0; j < segments; j++) {
        double t = j / segments;
        Color interpolatedColor = Color.lerp(startColor, endColor, t)!;
        smoothColors.add(interpolatedColor);
      }
    }

    // 添加最后一个颜色
    smoothColors.add(colors.last);
    return smoothColors;
  }

  // 创建对应的停靠点
  List<double> _createSmoothStops(List<Color> originalColors, int segments) {
    List<double> stops = [];
    int totalSegments = (originalColors.length - 1) * segments + 1;

    for (int i = 0; i < totalSegments; i++) {
      stops.add(i / (totalSegments - 1));
    }

    return stops;
  }

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width - strokeWidth) / 2;
    final rect = Rect.fromCircle(center: center, radius: radius);

    // 计算可用的弧度（完整圆减去间隙）
    final availableAngle = 2 * 3.14159 - gapAngle;
    final startAngle = _startAngle;

    // 绘制背景圆弧
    final backgroundPaint = Paint()
      ..color = backgroundColor
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    canvas.drawArc(
      rect,
      startAngle,
      availableAngle,
      false,
      backgroundPaint,
    );

    // 绘制进度圆弧
    if (progress > 0) {
      final progressAngle = availableAngle * progress;

      // 使用分段绘制方法确保颜色准确性
      _drawSegmentedProgress(canvas, rect, startAngle, progressAngle);
    }
  }

  // 改进的分段绘制方法，确保起始颜色准确
  void _drawSegmentedProgress(Canvas canvas, Rect rect, double startAngle, double progressAngle) {
    const int totalSegments = 120; // 增加段数以获得更平滑的效果
    final segmentAngle = progressAngle / totalSegments;

    for (int i = 0; i < totalSegments; i++) {
      final segmentStart = startAngle + i * segmentAngle;
      final segmentProgress = i / (totalSegments - 1); // 当前段在整个进度中的位置 (0.0 - 1.0)

      // 确保起始位置使用第一个颜色
      Color currentColor;
      if (i == 0) {
        currentColor = gradientColors.first;
      } else if (i == totalSegments - 1) {
        // 最后一段使用计算出的颜色，但要考虑实际进度
        currentColor = _getColorAtProgress(1.0);
      } else {
        currentColor = _getColorAtProgress(segmentProgress);
      }

      final segmentPaint = Paint()
        ..color = currentColor
        ..strokeWidth = strokeWidth
        ..style = PaintingStyle.stroke
        ..strokeCap = StrokeCap.round; // 只有第一段使用圆角

      canvas.drawArc(
        rect,
        segmentStart,
        segmentAngle,
        false,
        segmentPaint,
      );
    }
  }

  // 根据进度百分比获取对应的颜色
  Color _getColorAtProgress(double t) {
    if (gradientColors.length < 2) return gradientColors.first;

    // 将进度映射到颜色段
    final colorIndex = t * (gradientColors.length - 1);
    final colorIndexFloor = colorIndex.floor();
    final colorIndexCeil = colorIndex.ceil();

    if (colorIndexFloor == colorIndexCeil) {
      return gradientColors[colorIndexFloor.clamp(0, gradientColors.length - 1)];
    }

    final localT = colorIndex - colorIndexFloor;
    final startColor = gradientColors[colorIndexFloor.clamp(0, gradientColors.length - 1)];
    final endColor = gradientColors[colorIndexCeil.clamp(0, gradientColors.length - 1)];

    return Color.lerp(startColor, endColor, localT)!;
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

// 使用示例
class ProgressRingDemo extends StatefulWidget {
  @override
  _ProgressRingDemoState createState() => _ProgressRingDemoState();
}

class _ProgressRingDemoState extends State<ProgressRingDemo> {
  double _progress = 0.68;
  GapDirection _gapDirection = GapDirection.bottom;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xffFDF2F8),
      appBar: AppBar(
        title: const Text('Progress Ring Demo'),
        backgroundColor: Colors.transparent,
        elevation: 0,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 主要的进度圆环 - 模仿图片样式
            ProgressRing(
              progress: _progress,
              size: 200,
              strokeWidth: 16,
              showShadow: false,

              animationDuration: const Duration(milliseconds: 1200),
              gapAngle: 2, // 开口大小
              gapDirection: _gapDirection, // 可变开口方向
              gradientColors: const [
                Color(0xffC184FB), // 紫色
                Color(0xffC9FDF9), // 蓝色
                Color(0xffF473B7), // 青色
                Color(0xFFFF6B9D), // 粉色
              ],
              backgroundColor: Colors.white,
            ),
            const SizedBox(height: 40),
            // 控制按钮
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _progress = 0.25;
                    });
                  },
                  child: const Text('25%'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _progress = 0.50;
                    });
                  },
                  child: const Text('50%'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _progress = 0.75;
                    });
                  },
                  child: const Text('75%'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _progress = 1.0;
                    });
                  },
                  child: const Text('100%'),
                ),
              ],
            ),
            const SizedBox(height: 20),
            // 方向控制按钮
            const Text('开口方向:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            const SizedBox(height: 10),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _gapDirection = GapDirection.top;
                    });
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: _gapDirection == GapDirection.top ? Colors.blue : null,
                  ),
                  child: const Text('上'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _gapDirection = GapDirection.right;
                    });
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: _gapDirection == GapDirection.right ? Colors.blue : null,
                  ),
                  child: const Text('右'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _gapDirection = GapDirection.bottom;
                    });
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: _gapDirection == GapDirection.bottom ? Colors.blue : null,
                  ),
                  child: const Text('下'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _gapDirection = GapDirection.left;
                    });
                  },
                  style: ElevatedButton.styleFrom(
                    backgroundColor: _gapDirection == GapDirection.left ? Colors.blue : null,
                  ),
                  child: const Text('左'),
                ),
              ],
            ),
            // 小尺寸示例 - 展示四个方向的开口
            const SizedBox(height: 20),
            const Text('四个方向示例:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            const SizedBox(height: 15),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Column(
                  children: [
                    ProgressRing(
                      progress: 0.75,
                      size: 80,
                      strokeWidth: 6,
                      gapAngle: 0.6,
                      gapDirection: GapDirection.top, // 顶部开口
                      gradientColors: const [
                        Color(0xFF4FACFE),
                        Color(0xFF00F2FE),
                      ],
                    ),
                    const SizedBox(height: 8),
                    const Text('顶部开口', style: TextStyle(fontSize: 12)),
                  ],
                ),
                Column(
                  children: [
                    ProgressRing(
                      progress: 0.6,
                      size: 80,
                      strokeWidth: 6,
                      gapAngle: 0.6,
                      gapDirection: GapDirection.right, // 右侧开口
                      gradientColors: const [
                        Color(0xFFFF9A8B),
                        Color(0xFFFAD0C4),
                        Color(0xFFFFD93D),
                      ],
                    ),
                    const SizedBox(height: 8),
                    const Text('右侧开口', style: TextStyle(fontSize: 12)),
                  ],
                ),
                Column(
                  children: [
                    ProgressRing(
                      progress: 0.9,
                      size: 80,
                      strokeWidth: 6,
                      gapAngle: 0.6,
                      gapDirection: GapDirection.bottom, // 底部开口
                      gradientColors: const [
                        Color(0xFFA8EDEA),
                        Color(0xFFFED6E3),
                        Color(0xFFD299C2),
                      ],
                    ),
                    const SizedBox(height: 8),
                    const Text('底部开口', style: TextStyle(fontSize: 12)),
                  ],
                ),
                Column(
                  children: [
                    ProgressRing(
                      progress: 0.45,
                      size: 80,
                      strokeWidth: 6,
                      gapAngle: 0.6,
                      gapDirection: GapDirection.left, // 左侧开口
                      gradientColors: const [
                        Color(0xFFFFB347),
                        Color(0xFFFFCC70),
                        Color(0xFFFFF8DC),
                      ],
                    ),
                    const SizedBox(height: 8),
                    const Text('左侧开口', style: TextStyle(fontSize: 12)),
                  ],
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
